#include "scheduler/reactive_fallback_scheduler.h"
#include "../policy/policy_factory.h"
#include "../policy/behavior_tree/behavior_tree_reactive_fallback_policy.h"

namespace scheduler
{
ReactiveFallbackScheduler::ReactiveFallbackScheduler(const std::string &name)
    : AbstractScheduler(name)
{
    schedule_policy_ = policy::PolicyFactory<policy::BehaviorTreeReactiveFallbackPolicy>::createPolicy(name);
}
bool ReactiveFallbackScheduler::setReactiveTask(const task::AbstractTaskConstPtr &task)
{
    if (task->getTaskType() == task::TaskType::SYNC_TASK)
    {
        EASE_ERROR("reactive fallback scheduler appended reactive task cannot be sync task, must request task");
        throw std::runtime_error("reactive fallback scheduler appended reactive task cannot be sync task, must request task");
    }
    else if (task->getTaskType() == task::TaskType::SYNC_REQUEST_TASK)
    {
        auto policy = dynamic_cast<policy::BehaviorTreeReactiveFallbackPolicy *>(schedule_policy_.get());
        if (nullptr == policy)
        {
            throw std::runtime_error("reactive fallback scheduler policy case fail");
        }
        return policy->setReactiveTask(task);
    }
    else
    {
        EASE_ERROR("reactive fallback scheduler appended reactive task error");
        throw std::runtime_error("reactive fallback scheduler appended reactive task error");
    }
}
bool ReactiveFallbackScheduler::setReactiveScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeReactiveFallbackPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive fallback scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setReactivePolicy(scheduler->getTaskPolicy());
}
bool ReactiveFallbackScheduler::appendExecuteTask(const task::AbstractTaskConstPtr &task)
{
    return AbstractScheduler::appendTask(task);
}
bool ReactiveFallbackScheduler::appendExecuteScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    return AbstractScheduler::appendScheduler(scheduler);
}
bool ReactiveFallbackScheduler::appendScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive fallback cannot append scheduler");
    throw std::runtime_error("reactive fallback scheduler cannot append scheduler");
}
bool ReactiveFallbackScheduler::setTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive fallback cannot set task");
    throw std::runtime_error("reactive fallback fallback cannot set task");
}
bool ReactiveFallbackScheduler::setScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive fallback cannot set scheduler");
    throw std::runtime_error("reactive fallback scheduler cannot set scheduler");
}
bool ReactiveFallbackScheduler::appendTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive fallback cannot append scheduler");
    throw std::runtime_error("reactive fallback scheduler cannot append scheduler");
}
ReactiveFallbackScheduler::~ReactiveFallbackScheduler() = default;
}

